// **************************************************************
// COPYRIGHT(c)2020, Xidian University
// All rights reserved.
//
// IP LIB INDEX :  
// IP Name      :      
// File name    : insert_capture_top.v
// Module name  : insert_capture_top
// Full name    :  
//
// Author       : lhb
// Email        : 2296971136@qq.com
// Data         : 2021/5/25
// Version      : V 1.1 
// 
// Abstract     : 
// Called by    : NP_top
// Note         : 
// Modification history
// -----------------------------------------------------------------
// v1.1 after decode 21bit address, modify some syntax error----wzk,2022/5/4
// 
// 
// *****************************************************************
`timescale 1ns/1ps 
`include "top_define.v"
module insert_capture_top(
                    input  wire         rst_n                         ,
                    input  wire         clk                         ,
                    input  wire [9:0]  ram_2p_cfg_register      ,
                    // ¨¦???????????
                    output reg  [31:0]np_data_out                   ,
                    input  wire [31:0]np_data_in                    ,
                    input  wire [16:0]np_addr_in                    ,
                    input  wire [ 1:0]np_addr_ctrl       ,
                    output reg ins_cpt_rd_vld,
                    //?????¡¦E????
		    input  wire			cpt_em_data_val             ,
		    input  wire [255:0]	cpt_em_data		            ,
                    input  wire			em_cpt_en                   ,
                    input  wire [7:0]	em_hm_id                    ,
                    input  wire [10:0]	em_cpt_frame_len            ,
                    //?????¡¦H????
                    input  wire 		cpt_hm_data_val             ,
                    input  wire [255:0]	cpt_hm_data		            ,
                    input  wire 		hm_cpt_en                   ,
                    input  wire [7:0]	hm_hm_id                    ,
                    input  wire [10:0]	hm_cpt_frame_len            ,
					

                    output wire         cpt_busy                    ,
					//??????E????
                    output wire [2:0]   pri_insert_e                ,
                    output wire         insert_empty_e              ,
                    input  wire         rx_rdy_insert_e             ,
					output wire [7:0]   insert_des_node_id_insert_e ,
                    output wire [255:0] rx_ff_data_insert_e	        ,
                    output wire         rx_ff_dval_insert_e	        ,
                    output wire         rx_ff_sop_insert_e	        ,
                    output wire         rx_ff_eop_insert_e	        ,
                    output wire [4:0]   rx_ff_mod_insert_e	        ,
                    output wire         rx_ff_dsav_insert_e	        ,
                    //??????H????
                    output wire [2:0]   pri_insert_h                ,
                    output wire         insert_empty_h              ,
                    input  wire         rx_rdy_insert_h             ,																  
                    output wire [7:0]   insert_des_node_id_insert_h ,
                    output wire [255:0] rx_ff_data_insert_h	        ,
                    output wire         rx_ff_dval_insert_h	        ,
                    output wire         rx_ff_sop_insert_h	        ,
                    output wire         rx_ff_eop_insert_h	        ,
                    output wire [4:0]   rx_ff_mod_insert_h	        ,
                    output wire         rx_ff_dsav_insert_h	        

);
 wire [10:0]  insert_frame_len;
wire             [255:0]    dpram_data                    ;
wire             [5:0]	    dpram_addr_insert             ;
//================================================================
wire wren_i ;
wire rden_i;
assign wren_i = np_addr_ctrl[1];
assign rden_i = np_addr_ctrl[0];

//----------------------------------------------------------
reg reg_wr_en;
reg reg_rd_en;
always@(posedge clk or negedge rst_n)begin
    if(~rst_n)
        reg_wr_en <= 1'b0;
    else if(wren_i)
        reg_wr_en <= !(|np_addr_in[16:10]);
    else
        reg_wr_en <= 1'b0;
end

always@(posedge clk or negedge rst_n)begin
    if(~rst_n)
        reg_rd_en <= 1'b0;
    else if(rden_i)
        reg_rd_en <= !(|np_addr_in[16:10]);
    else
        reg_rd_en <= 1'b0;
end

//----------------------------------------------------------
reg ins_wr_en;
reg cpt_rd_en;
reg [31:0]cpu_ins_data_i ;
reg [11:0]cpu_rdcpt_addr_i;
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)begin
        cpu_ins_data_i <= 32'b0;
        ins_wr_en <= 1'b0;
    end else if(wren_i && np_addr_in[16:10]>=`INSERT_BASE_ADDR && np_addr_in[16:10]<`CAPTURE_BASE_ADDR) begin
        cpu_ins_data_i <= np_data_in;
        ins_wr_en <= 1'b1;
    end else begin
        ins_wr_en <= 1'b0;
    end
end

always @(posedge clk or negedge rst_n) begin
    if(~rst_n)begin
        cpu_rdcpt_addr_i <= 12'b0;
        cpt_rd_en <= 1'b0;
    end else if(rden_i && np_addr_in[16:10]>=`CAPTURE_BASE_ADDR && np_addr_in[16:10]<`SRAM_BASE_ADDR)begin
        cpu_rdcpt_addr_i <= np_addr_in[11:0];
        cpt_rd_en <= 1'b1;
    end else begin
        cpt_rd_en <= 1'b0;
    end
end
//---------------------------------------------------------

reg [31:0]np_data_in_d1;
reg cpt_rd_en_d1;
reg [16:0]np_addr_in_d1;
wire [31:0]  cpu_rdcpt_data_o;
wire [31:0]  dpram_status_o;
wire [31:0]  cpt_fifo_status_o    ;

always @(posedge clk or negedge rst_n) begin
    if(~rst_n)begin

        np_data_in_d1   <= 32'b0;
        cpt_rd_en_d1    <= 1'b0;
        np_addr_in_d1   <= 17'b0;
    end else begin
        np_data_in_d1   <= np_data_in;
        cpt_rd_en_d1    <= cpt_rd_en;
        np_addr_in_d1   <= np_addr_in    ;
    end
end
//---------------------------------------------------------------
reg [1:0]capture_ins_register_i;
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        capture_ins_register_i <= 2'b0;
    else if(reg_wr_en && np_addr_in_d1[6:0]==`ADDR_CAP_INS)
        capture_ins_register_i <= np_data_in_d1[1:0];
end
reg insert_ins_register_i;
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        insert_ins_register_i <= 1'b0;
    else if(reg_wr_en && np_addr_in_d1[6:0]==`ADDR_INSERT_INS)
        insert_ins_register_i <= np_data_in_d1[0];
end
reg [10:0]insert_frm_info_register_i;
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        insert_frm_info_register_i <= 11'b0;
    else if(reg_wr_en && np_addr_in_d1[6:0]==`ADDR_INSERT_FRM_INFO)
        insert_frm_info_register_i <= np_data_in_d1[10:0];
end
reg [10:0]insert_frm_len_register_i;
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        insert_frm_len_register_i <= 11'b0;
    else if(reg_wr_en && np_addr_in_d1[6:0]==`ADDR_INSERT_FRM_LEN)
        insert_frm_len_register_i <= np_data_in_d1[11:0];
end
//------------------------------------------------------------------
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)begin
        np_data_out <= 32'b0;
        ins_cpt_rd_vld <= 1'b0;
    end else if(cpt_rd_en_d1)begin
        np_data_out <= cpu_rdcpt_data_o;
        ins_cpt_rd_vld <= 1'b1;
    end else if(reg_rd_en && np_addr_in_d1[6:0]==`ADDR_CAP_STAT)begin
        np_data_out <= cpt_fifo_status_o;
        ins_cpt_rd_vld <= 1'b1;
    end else if(reg_rd_en && np_addr_in_d1[6:0]==`ADDR_DPRAM_STAT)begin
        np_data_out <= dpram_status_o;
        ins_cpt_rd_vld <= 1'b1;
    end else if(reg_rd_en && np_addr_in_d1[6:0]==`ADDR_INSERT_FRM_LEN)begin
        np_data_out <= {21'b0,insert_frm_len_register_i};
        ins_cpt_rd_vld <= 1'b1;
    end else if(reg_rd_en && np_addr_in_d1[6:0]==`ADDR_CAP_INS)begin
        np_data_out <= {30'b0,capture_ins_register_i};
        ins_cpt_rd_vld <= 1'b1;
    end else if(reg_rd_en && np_addr_in_d1[6:0]==`ADDR_INSERT_INS)begin
        np_data_out <= {31'b0,insert_ins_register_i};
        ins_cpt_rd_vld <= 1'b1;
    end else if(reg_rd_en && np_addr_in_d1[6:0]==`ADDR_INSERT_FRM_INFO)begin
        np_data_out <= {21'b0,insert_frm_info_register_i};
        ins_cpt_rd_vld <= 1'b1;
    end else begin
        ins_cpt_rd_vld <= 1'b0;
    end
end
//=============================================================================
insert_cpu_w_ctrl U_insert_cpu_w_ctrl(
	.clk       (clk)                        ,
	.rst_n           (rst_n)                        ,
    .ram_2p_cfg_register(ram_2p_cfg_register),
    .insert_end    (insert_ins_register_i)   ,
   
	.dpram0_wren   (ins_wr_en      )       ,
	.dpram0_wdata  (cpu_ins_data_i      )       ,
	.dpram0_raddr  (dpram_addr_insert )         ,
	.dpram0_rdata  (dpram_data        )
    );

CPT_CTRL_NEW #(.CPT_WIDTH(12), .CPT_NUM_WIDTH(8))
U_CPT_CTRL_NEW(
            //input
            .clk                   (clk)                        ,
            .rst_n                 (rst_n)                       ,
			.ram_2p_cfg_register(ram_2p_cfg_register),						
			//???????¡è????h            
	        .cpt_hm_data_val       (cpt_hm_data_val )           ,
            .cpt_hm_data           (cpt_hm_data	 )              ,
			.hm_cpt_en             (hm_cpt_en       )           ,
			.hm_hm_id              (hm_hm_id        )           ,
			.hm_cpt_frame_len      (hm_cpt_frame_len)           , 
			//???????¡è????e            
			.cpt_em_data_val       (cpt_em_data_val )           ,
            .cpt_em_data           (cpt_em_data	 )              ,
			.em_cpt_en             (em_cpt_en       )           ,
			.em_hm_id              (em_hm_id        )           ,
			.em_cpt_frame_len      (em_cpt_frame_len)           , 
																		
            .rd_rdy                (capture_ins_register_i[0])  ,
            .rd_end                (capture_ins_register_i[1])  ,
									
		    //2013.8.20 zhangjy         									
            .cpu_rdcpt_en          (cpt_rd_en  )           ,
            .cpu_rdcpt_addr        (cpu_rdcpt_addr_i)     ,
            .cpu_rdcpt_data        (cpu_rdcpt_data_o)           ,
									
            .cpt_fifo_status       (cpt_fifo_status_o)          ,
									
            .cpt_busy		       (cpt_busy)
           );  


insert_new  U_insert_new(
                       //input
                       .clk                    (clk)                                ,
                       .rst_n                    (rst_n)                                ,
											   
					   //connect cpu interfase 
                       .insert_end             (insert_ins_register_i)           ,
                       .frame_pri              (insert_frm_info_register_i[2:0])    ,
                       .frame_len              (insert_frm_len_register_i[10:0])    ,
                       .des_id                 (insert_frm_info_register_i[10:3])  ,
                       .dpram_status           (dpram_status)                       ,
											   
					   //????????¡ã???              
		       .dpram0_data            (dpram_data		    )               ,
                       .dpram0_addr            (dpram_addr_insert	)               ,

					   //???????¡è????E????
                       .frame_pri_o_e          (pri_insert_e			    )       ,
                       .des_id_o_e             (insert_des_node_id_insert_e	)       ,
                       .empty_e                (insert_empty_e				)       ,
                       .insert_data_rdy_e      (rx_rdy_insert_e		        )       ,
                       .insert_data_o_e        (rx_ff_data_insert_e	        )       ,
                       .insert_data_val_o_e    (rx_ff_dval_insert_e	        )       ,
                       .insert_data_sop_e      (rx_ff_sop_insert_e	        )       ,
                       .insert_data_eop_e      (rx_ff_eop_insert_e	        )       ,
                       .insert_data_mode_e     (rx_ff_mod_insert_e	        )       ,
                       .insert_data_dsav_e     (rx_ff_dsav_insert_e	        )       ,
											   
					   //???????¡è????H????
                       .frame_pri_o_h          (pri_insert_h			    )       ,
                       .des_id_o_h             (insert_des_node_id_insert_h	)       ,
                       .empty_h                (insert_empty_h				)       ,
                       .insert_data_rdy_h      (rx_rdy_insert_h		        )       ,
                       .insert_data_o_h        (rx_ff_data_insert_h	        )       ,
                       .insert_data_val_o_h    (rx_ff_dval_insert_h	        )       ,        
                       .insert_data_sop_h      (rx_ff_sop_insert_h	        )       ,
                       .insert_data_eop_h      (rx_ff_eop_insert_h	        )       ,
                       .insert_data_mode_h     (rx_ff_mod_insert_h	        )       ,
                       .insert_data_dsav_h     (rx_ff_dsav_insert_h	        )   
                      );

assign dpram_status_o = {31'b0,dpram_status};
assign insert_frame_len = insert_frm_len_register_i[10:0];

endmodule
